/*
 * Copyright 2010 Alessandro Bellucci
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.soupframework.gwt.designerpanel.client.interaction.impl;

import java.util.HashMap;

import org.soupframework.gwt.designerpanel.client.DesignerPanel;
import org.soupframework.gwt.designerpanel.client.designer.ContainerDesigner;
import org.soupframework.gwt.designerpanel.client.designer.Designer;
import org.soupframework.gwt.designerpanel.client.interaction.InteractionHandler;
import org.soupframework.gwt.designerpanel.client.interaction.InteractionHandlerManager;
import org.soupframework.gwt.designerpanel.client.interaction.InteractionMode;
import org.soupframework.gwt.designerpanel.client.interaction.NewObjectsHandler;
import org.soupframework.gwt.designerpanel.client.interaction.ResizeMode;

public abstract class InteractionHandlerManagerBase<T> implements InteractionHandlerManager<T> {

	private HashMap<Designer<T>, InteractionHandler<T>> interactionHandlers = new HashMap<Designer<T>, InteractionHandler<T>>();

	private Designer<T> rootDesigner;

	private boolean interactionEnabled = true;

	private ResizeMode resizeMode;

	private T resizingObject;

	/**
	 * {@link InteractionMode} with the {@link DesignerPanel}
	 */
	private InteractionMode interactionMode = InteractionMode.SELECT;

	/**
	 * Handler for the addition of new widgets to target container.
	 */
	private NewObjectsHandler<T> newWidgetsHandler;

	protected InteractionHandlerManagerBase(Designer<T> rootDesigner){
		this.rootDesigner = rootDesigner;
	}

	@Override
	public Designer<T> getRootDesigner() {
		return rootDesigner;
	}

	@Override
	public boolean isInteractionEnabled() {
		return interactionEnabled;
	}

	@Override
	public InteractionHandler<T> getInteractionHandler(Designer<T> designer){
		if(this.interactionHandlers.get(designer) != null){
			return this.interactionHandlers.get(designer);
		}
		InteractionHandler<T> ihandler = this.createInteractionHandler(designer);
		this.interactionHandlers.put(designer, ihandler);
		return ihandler;
	}

	protected abstract InteractionHandler<T> createInteractionHandler(Designer<T> designer);

	@Override
	public void disableInteraction() {
		this.interactionEnabled = false;
	}

	@Override
	public void enableInteraction() {
		this.interactionEnabled = true;
	}

	@Override
	public InteractionMode getInteractionMode() {
		return interactionMode;
	}

	@Override
	public void setInteractionMode(InteractionMode mouseInteractionMode) {
		if(this.interactionMode != mouseInteractionMode){
			System.out.println(this.interactionMode + " -> " + mouseInteractionMode);
		}
		this.interactionMode = mouseInteractionMode;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ContainerDesigner<T> getSelectionRootDesigner() {
		Designer<T> d = this.getRootDesigner();
		if(d instanceof ContainerDesigner){
			return this.getSelectionRootDesigner((ContainerDesigner<T>)d);
		}
		return null;
	}

	private ContainerDesigner<T> getSelectionRootDesigner(ContainerDesigner<T> cd) {
		if(cd.getSelectedObjectsCount(false) > 0){
			return cd;
		}
		ContainerDesigner<T> ret = null;
		for(ContainerDesigner<T> child : cd.getChildrenContainerDesigners()){
			ContainerDesigner<T> childRoot = getSelectionRootDesigner(child);
			if(childRoot != null){
				if(ret == null){
					ret = childRoot;
				}
				else{
					// if more then one descendant has some selected widget there is no root designer for selection
					return null;
				}
			}
		}
		return ret;
	}

	@Override
	public NewObjectsHandler<T> getNewObjectsHandler() {
		return newWidgetsHandler;
	}

	@Override
	public void setNewWidgetsHandler(NewObjectsHandler<T> newWidgetsHandler) {
		this.newWidgetsHandler = newWidgetsHandler;
	}

	@Override
	public ResizeMode getResizeMode() {
		return resizeMode;
	}

	@Override
	public void setResizeMode(ResizeMode resizeMode) {
		this.resizeMode = resizeMode;
	}

	@Override
	public T getResizingObject() {
		return resizingObject;
	}

	@Override
	public void setResizingObject(T resizingObject) {
		this.resizingObject = resizingObject;
	}
}
